/*
 * Copyright (c) 2020-2021. the original authors and DEPSEA.ORG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.depsea.log.model;

import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.web.method.HandlerMethod;

import java.util.Date;

/**
 * 异常信息
 *
 * @author Wang Chengwei
 * @since 1.0.0 2021/11/3 9:55
 */
@Data
public class ExceptionInfo {

    /**
     * 应用名称
     */
    private String applicationName;

    /**
     * 本地服务器IP
     */
    private String serverLocalIp;

    /**
     * 请求参数，本来是map但是为了能够在存储到ES中时，不因数据类型和字段发生变更而导致一些错误，所以使用字符串
     */
    private String requestParameterMap;

    /**
     * 请求地址
     */
    private String requestUrl;

    /**
     * 请求方法
     */
    private String requestMethod;

    /**
     * 接口类的名称
     */
    private String className;

    /**
     * 接口方法的名称
     */
    private String methodName;

    /**
     * 异常信息
     */
    private String message;

    /**
     * 异常栈
     */
    private String exceptionStack;

    /**
     * 异常发生时间
     */
    @Field(type = FieldType.Date, format = DateFormat.date_time)
    private Date timestamp;

    public static ExceptionInfo create(String applicationName, Object handler, Exception ex) {
        ExceptionInfo exceptionInfo = new ExceptionInfo();
        exceptionInfo.setApplicationName(applicationName);
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            exceptionInfo.setMethodName(handlerMethod.getMethod().getName());
            exceptionInfo.setClassName(handlerMethod.getMethod().getDeclaringClass().getName());
        }
        exceptionInfo.setTimestamp(new Date());
        exceptionInfo.setExceptionStack(ExceptionUtils.getStackTrace(ex));
        exceptionInfo.setMessage(ex.getMessage());
        return exceptionInfo;
    }
}
